﻿using Kingdee.BOS.App.Data;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.Bill;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.EntityElement;
using Kingdee.BOS.Orm;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using Kingdee.K3.Core.Mobile.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PMAF.K3Cloud.SCM.BillList.BusinessPlugIn
{
    [HotUpdate]
    [Description("销售订单列表：远期订单保证金测算")]
    public class EarnestCalculate : AbstractDynamicFormPlugIn
    {
        private int successTimes = 0;
        /// <summary>
        /// 初始加载
        /// </summary>
        /// <param name="e"></param>
        public override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            //接收传递过来的单据编号
            string ids = View.OpenParameter.GetCustomParameter("ids").ToString();
            string entryIds = View.OpenParameter.GetCustomParameter("entryIds").ToString();
            //查询单据明细
            string sql = string.Format(@"/*dialect*/
            SELECT
            t1.FID,
            t0.FENTRYID,
            t0.FSEQ,
            t1.FDATE,
            t1.FBILLNO,
            t1.FCUSTID,
            t1.FSALERID,
            t1.FSALEDEPTID,
            t1.FSALEORGID,
            t0.FMATERIALID,
            t0.FUNITID,
            t0.FQTY,
            t2.FTAXPRICE,
            t0.FQTY*t2.FTAXPRICE*t7.FASSOCIATEMARGIN/t7.FBILLALLAMOUNT AS BASEEARNEST,
            t0.F_PMAF_RECIEVEDEARNEST AS RECIEVEDEARNEST,
            t3.FDELIVERYDATE AS DELIVERYDATE,
            t0.F_PMAF_UNDELIVERYQTY AS UNDELIVERYQTY,
            t0.F_PMAF_PURCHASESN
            FROM T_SAL_ORDERENTRY t0
            LEFT JOIN T_SAL_ORDER t1 ON t1.FID=t0.FID
            LEFT JOIN T_SAL_ORDERENTRY_F t2 ON t2.FID=t0.FID AND t2.FENTRYID=t0.FENTRYID
            LEFT JOIN T_SAL_ORDERENTRY_D t3 ON t3.FID=t0.FID AND t3.FENTRYID=t0.FENTRYID
            LEFT JOIN PMAF_t_PurchaseSn t4 ON t4.FID=t0.F_PMAF_PURCHASESN
            LEFT JOIN T_SAL_ORDERFIN t7 ON t7.FID=t0.FID
            WHERE
            t0.FID IN {0}
            AND t0.FENTRYID IN {1}
            ", ids, entryIds);
            DynamicObjectCollection dt = DBUtils.ExecuteDynamicObject(Context, sql);
            if (dt.Count > 0)
            {
                //构建保证金测算明细
                Entity entity = View.BillBusinessInfo.GetEntity("F_PMAF_EarnestCalculateEntry");
                //转换成行
                DynamicObjectCollection rows = Model.GetEntityDataObject(entity);
                //明细行索引
                int i = 0;
                foreach (DynamicObject dtRow in dt)
                {
                    //基础资料数据模型
                    FormMetadata customerMeta = MetaDataServiceHelper.Load(Context, "BD_Customer") as FormMetadata;
                    FormMetadata salerMeta = MetaDataServiceHelper.Load(Context, "BD_SALER") as FormMetadata;
                    FormMetadata departmentMeta = MetaDataServiceHelper.Load(Context, "BD_DEPARTMENT") as FormMetadata;
                    FormMetadata materialMeta = MetaDataServiceHelper.Load(Context, "BD_Material") as FormMetadata;
                    FormMetadata organizationsMeta = MetaDataServiceHelper.Load(Context, "ORG_ORGANIZATIONS") as FormMetadata;
                    FormMetadata unitMeta = MetaDataServiceHelper.Load(Context, "BD_UNIT") as FormMetadata;
                    FormMetadata purchaseSnMeta = MetaDataServiceHelper.Load(Context, "PMAF_PurchaseSn") as FormMetadata;

                    //基础资料ID及数据包
                    int customerId = Convert.ToInt32(dtRow["FCUSTID"]);
                    DynamicObject customer = BusinessDataServiceHelper.LoadSingle(Context, customerId, customerMeta.BusinessInfo.GetDynamicObjectType());
                    int salerId = Convert.ToInt32(dtRow["FSALERID"]);
                    DynamicObject saler = BusinessDataServiceHelper.LoadSingle(Context, salerId, salerMeta.BusinessInfo.GetDynamicObjectType());
                    int departmentId = Convert.ToInt32(dtRow["FSALEDEPTID"]);
                    DynamicObject department = BusinessDataServiceHelper.LoadSingle(Context, departmentId, departmentMeta.BusinessInfo.GetDynamicObjectType());
                    int materialId = Convert.ToInt32(dtRow["FMATERIALID"]);
                    DynamicObject material = BusinessDataServiceHelper.LoadSingle(Context, materialId, materialMeta.BusinessInfo.GetDynamicObjectType());
                    int organizationsId = Convert.ToInt32(dtRow["FSALEORGID"]);
                    DynamicObject organizations = BusinessDataServiceHelper.LoadSingle(Context, organizationsId, organizationsMeta.BusinessInfo.GetDynamicObjectType());
                    int unitId = Convert.ToInt32(dtRow["FUNITID"]);
                    DynamicObject unit = BusinessDataServiceHelper.LoadSingle(Context, unitId, unitMeta.BusinessInfo.GetDynamicObjectType());
                    int purchaseId = Convert.ToInt32(dtRow["F_PMAF_PURCHASESN"]);
                    DynamicObject purchase = null;
                    if (purchaseId != 0)
                    {
                        purchase = BusinessDataServiceHelper.LoadSingle(Context, purchaseId, purchaseSnMeta.BusinessInfo.GetDynamicObjectType());
                    }

                    //每行的值定义成DynamicObject
                    DynamicObject row = new DynamicObject(entity.DynamicObjectType);
                    //赋值seq
                    entity.SeqDynamicProperty.SetValue(row, i + 1);
                    //赋值第i行数据
                    row["F_PMAF_FID"] = Convert.ToInt32(dtRow["FID"]);
                    row["F_PMAF_FEntryId"] = Convert.ToInt32(dtRow["FENTRYID"]);
                    row["F_PMAF_SrcMaterialSeq"] = dtRow["FSEQ"];
                    row["F_PMAF_OrderDate"] = dtRow["FDATE"].ToString();
                    row["F_PMAF_OrderBillNo"] = dtRow["FBILLNO"].ToString();
                    row["F_PMAF_CustomerId_Id"] = customerId;
                    row["F_PMAF_CustomerId"] = customer;
                    row["F_PMAF_SalerId_Id"] = salerId;
                    row["F_PMAF_SalerId"] = saler;
                    row["F_PMAF_SaleDeptId_Id"] = departmentId;
                    row["F_PMAF_SaleDeptId"] = department;
                    row["F_PMAF_SaleOrgId_Id"] = organizationsId;
                    row["F_PMAF_SaleOrgId"] = organizations;
                    row["F_PMAF_MaterialId_Id"] = materialId;
                    row["F_PMAF_MaterialId"] = material;
                    row["F_PMAF_UnitId_Id"] = unitId;
                    row["F_PMAF_UnitId"] = unit;
                    row["F_PMAF_SaleQty"] = dtRow["FQTY"];
                    row["F_PMAF_SalePrice"] = dtRow["FTAXPRICE"];
                    row["F_PMAF_BaseEarnest"] = dtRow["BASEEARNEST"];
                    row["F_PMAF_RecievedEarnest"] = dtRow["RECIEVEDEARNEST"];
                    row["F_PMAF_UnDeliveryQty"] = dtRow["UNDELIVERYQTY"];
                    row["F_PMAF_DeliveryDate"] = dtRow["DELIVERYDATE"];
                    row["F_PMAF_PurchaseSn_Id"] = purchaseId;
                    row["F_PMAF_PurchaseSn"] = purchase;
                    rows.Add(row);
                    i++;
                }
            }
        }

        public override void BarItemClick(BarItemClickEventArgs e)
        {
            base.BarItemClick(e);
            switch (e.BarItemKey.ToUpperInvariant())
            {
                case "PMAF_NEWEARNESTNOTICEBTN":
                    if (successTimes > 0)
                    {
                        View.ShowWarnningMessage("已经生成保证金通知单了。不要重复生成哦！！");
                        return;
                    }
                    //构建保证金计算明细
                    Entity entity = View.BillBusinessInfo.GetEntity("F_PMAF_EarnestCalculateEntry");
                    //转换成行
                    DynamicObjectCollection rows = View.Model.GetEntityDataObject(entity);
                    int priceCount = 0;
                    StringBuilder sb = new StringBuilder();
                    HashSet<int[]> custOrgIds = new HashSet<int[]>();
                    //构建保证金通知单元数据
                    IMetaDataService metaService = ServiceFactory.GetService<IMetaDataService>(Context);
                    FormMetadata earnestNoticeMeta = (FormMetadata)metaService.Load(Context, "PMAF_EarnestNotice");
                    Entity earnestNoticeEntity = earnestNoticeMeta.BusinessInfo.GetEntity("FEntity");
                    List<DynamicObject> list = new List<DynamicObject>();
                    foreach (DynamicObject row in rows)
                    {
                        decimal currentPrice = Convert.ToDecimal(row["F_PMAF_CurrentPrice"]);
                        int[] custOrgId = new int[]
                        {
                            Convert.ToInt32(row["F_PMAF_CustomerId_Id"]),
                            Convert.ToInt32(row["F_PMAF_SaleOrgId_Id"])
                        };
                        custOrgIds = GetCustOrgIds(custOrgIds, custOrgId);
                        if (currentPrice != 0)
                        {
                            priceCount++;
                        }
                        else
                        {
                            string note = string.Format("第{0}行没有填写市场价格，请检查！", row["Seq"]);
                            sb.Append(note);
                        }
                    }
                    if (priceCount < rows.Count)
                    {
                        View.ShowWarnningMessage(sb.ToString());
                        return;
                    }
                    else
                    {
                        foreach (int[] custOrgId in custOrgIds)
                        {
                            //构建保证金通知单单据
                            DynamicObject earnestNotice = 
                                new DynamicObject(earnestNoticeMeta.BusinessInfo.GetDynamicObjectType());
                            earnestNotice["FFormId"] = "PMAF_EarnestNotice";
                            earnestNotice["DocumentStatus"] = "A";
                            earnestNotice["CancelStatus"] = "A";
                            earnestNotice["CreatorId_Id"] = Context.UserId;
                            earnestNotice["CreateDate"] = DateTime.Now;
                            earnestNotice["ModifierId_Id"] = Context.UserId;
                            earnestNotice["ModifyDate"] = DateTime.Now;
                            earnestNotice["F_PMAF_Date"] = DateTime.Now;
                            earnestNotice["F_PMAF_SaleOrgId_Id"] = custOrgId[1];
                            earnestNotice["F_PMAF_RecieveOrgId_Id"] = custOrgId[1];
                            earnestNotice["F_PMAF_SettleOrgId_Id"] = custOrgId[1];
                            earnestNotice["F_PMAF_PayUnitType"] = "BD_Customer";
                            earnestNotice["F_PMAF_PayUnit_Id"] = custOrgId[0];
                            earnestNotice["F_PMAF_CustomerId_Id"] = custOrgId[0];
                            earnestNotice["F_PMAF_CurrencyId_Id"] = 1;
                            earnestNotice["F_PMAF_ExchangeType_Id"] = 1;
                            earnestNotice["F_PMAF_ExchangeRate"] = 1.0000;
                            earnestNotice["F_PMAF_MainBookCurId_Id"] = 1;
                            earnestNotice["F_PMAF_AccountSystem_Id"] = 1;
                            decimal amountFor_H = 0;
                            //构建保证金通知单明细数据包
                            DynamicObjectCollection earnestNoticeEntry = (DynamicObjectCollection)earnestNotice["PMAF_EarnestNoticeEntry"];
                            foreach (DynamicObject row in rows)
                            {
                                //构建保证金通知单明细行数据包
                                DynamicObject dyo = new DynamicObject(earnestNoticeEntity.DynamicObjectType);
                                int eCustomerId = Convert.ToInt32(row["F_PMAF_CustomerId_Id"]);
                                int eOrganizationsId = Convert.ToInt32(row["F_PMAF_SaleOrgId_Id"]);
                                decimal amountFor = Convert.ToDecimal(row["F_PMAF_AmountFor"]);
                                if ((custOrgId[0] == eCustomerId && custOrgId[1] == eOrganizationsId) && amountFor > 0)
                                {
                                    amountFor_H += amountFor;
                                    dyo["F_PMAF_PurposeId_Id"] = 20700;
                                    dyo["F_PMAF_OrderBillNo"] = row["F_PMAF_OrderBillNo"];
                                    dyo["F_PMAF_MaterialId_Id"] = row["F_PMAF_MaterialId_Id"];
                                    dyo["F_PMAF_UnitId_Id"] = row["F_PMAF_UnitId_Id"];
                                    dyo["F_PMAF_OrderQty"] = row["F_PMAF_SaleQty"];
                                    dyo["F_PMAF_UnDeliveryQty"] = row["F_PMAF_UnDeliveryQty"];
                                    dyo["F_PMAF_OrderPrice"] = row["F_PMAF_SalePrice"];
                                    dyo["F_PMAF_CurrentPrice"] = row["F_PMAF_CurrentPrice"];
                                    dyo["F_PMAF_PriceGap"] = row["F_PMAF_PriceGap"];
                                    dyo["F_PMAF_Percentage"] = row["F_PMAF_Percentage"];
                                    dyo["F_PMAF_AmountFor_E"] = row["F_PMAF_AmountFor"];
                                    dyo["F_PMAF_Amount_E"] = row["F_PMAF_AmountFor"];
                                    dyo["F_PMAF_FID"] = row["F_PMAF_FID"];
                                    dyo["F_PMAF_FEntryID"] = row["F_PMAF_FEntryID"];
                                    dyo["F_PMAF_SrcMaterialSeq"] = row["F_PMAF_SrcMaterialSeq"];
                                    dyo["F_PMAF_BaseEarnest"] = row["F_PMAF_BaseEarnest"];
                                    dyo["F_PMAF_RecievedEarnest"] = row["F_PMAF_RecievedEarnest"];
                                    earnestNoticeEntry.Add(dyo);
                                }
                            }
                            earnestNotice["F_PMAF_AmountFor_H"] = amountFor_H;
                            earnestNotice["F_PMAF_Amount_H"] = amountFor_H;
                            list.Add(earnestNotice);
                        }
                        DynamicObject[] earnestNotices = list.ToArray();
                        if (earnestNotices.Length > 0)
                        {
                            ISaveService saveService = ServiceFactory.GetService<ISaveService>(Context);
                            IOperationResult saveResult = saveService.Save(Context, earnestNoticeMeta.BusinessInfo, earnestNotices, OperateOption.Create());
                            if (saveResult.IsSuccess)
                            {
                                successTimes++;
                                List<DynamicObject> result = (List<DynamicObject>)saveResult.SuccessDataEnity;
                                StringBuilder stringBuilder = new StringBuilder();
                                foreach(DynamicObject obj in result)
                                {
                                    stringBuilder.Append($"保证金通知单【{obj["BillNo"]}】").Append("保存成功；");
                                }
                                View.ShowMessage(stringBuilder.ToString());
                            }
                        }
                    }
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 查重客户与销售组织，按客户和销售组织的不同来创建单据
        /// </summary>
        /// <param name="custOrgIds"></param>
        /// <param name="custOrgId"></param>
        /// <returns></returns>
        private HashSet<int[]> GetCustOrgIds(HashSet<int[]> custOrgIds, int[] custOrgId)
        {
            HashSet<int[]> custOrgIds_ = new HashSet<int[]>();
            int count = 0;
            if (custOrgIds.Count == 0)
            {
                custOrgIds.Add(custOrgId);
            }
            else
            {
                foreach(int[] custOrgId_ in custOrgIds)
                {
                    if (custOrgId_[0] == custOrgId[0] && custOrgId_[1] == custOrgId[1])
                    {
                        count++;
                    }
                }
                if(count == 0)
                {
                    custOrgIds_.Add(custOrgId);
                }
            }
            custOrgIds.UnionWith(custOrgIds_);
            return custOrgIds;
        }
    }
}
